package com.cecil.generate.util;

import com.cecil.generate.constants.CommonConstants;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * jackson 工具
 */
@Slf4j
public class JsonUtil {

    private final static ObjectMapper mapper;

    static {
        mapper = new ObjectMapper();
        // 忽略json中在对象不存在对应属性
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 忽略空bean转json错误
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }

    /**
     * json转对象
     *
     * @param jsonStr json串
     * @param clz     对象类型
     * @return 对象
     */
    public static <T> T jsonToObj(String jsonStr, Class<T> clz) {
        if (jsonStr != null && !jsonStr.trim().isEmpty() && null != clz) {
            try {
                return mapper.readValue(jsonStr, clz);
            } catch (IOException e) {
                log.error("jsonToObj error.", e);
            }
        }
        return null;
    }

    /**
     * json转化为带泛型的对象
     *
     * @param jsonStr       json字符串
     * @param typeReference 转化类型
     * @return 对象
     */
    public static <T> T jsonToObjWithTypeReference(String jsonStr, TypeReference<T> typeReference) {
        if (jsonStr != null && !jsonStr.trim().isEmpty() && typeReference != null) {
            try {
                return mapper.readValue(jsonStr, typeReference);
            } catch (JsonProcessingException e) {
                log.error("jsonToObjWithTypeReference error.", e);
            }
        }
        return null;
    }

    /**
     * 对象转json
     *
     * @param obj 对象
     * @return json串
     */
    public static String objToJson(Object obj) {
        if (obj instanceof String) {
            return (String) obj;
        }
        try {
            return mapper.writeValueAsString(obj);
        } catch (IOException e) {
            log.error("objToJson error.", e);
            return CommonConstants.EMPTY;
        }
    }

    /**
     * 对象转json(格式化的json)
     *
     * @param obj 对象
     * @return 格式化的json串
     */
    public static String objToJsonWithFormat(Object obj) {
        if (obj instanceof String) {
            return (String) obj;
        }

        try {
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (IOException e) {
            log.error("objToJsonWithFormat error.", e);
            return CommonConstants.EMPTY;
        }
    }

    /**
     * json 转 List
     */
    public static <T> List<T> jsonToList(String jsonStr, Class<T> classType) {
        if (StringUtil.isNotEmpty(jsonStr) && classType != null) {
            try {
                return mapper.readValue(jsonStr, mapper.getTypeFactory().constructCollectionType(List.class, classType));
            } catch (IOException e) {
                System.out.println("json to list exception");
            }
        }
        return null;
    }

    /**
     * json 转 Map
     */
    public static <k, v> Map<k, v> jsonToMap(String json, Class<k> kType, Class<v> vType) {
        if (StringUtil.isNotEmpty(json)) {
            try {
                return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kType, vType));
            } catch (IOException e) {
                System.out.println("json to Map exception");
            }
        }
        return null;
    }

}
